#include "sessionfriendarea.h"

#include <QScrollBar>
#include <QVBoxLayout>
#include <QPushButton>
#include <QEnterEvent>
#include <QStyleOption>
#include <QPainter>
#include <QEnterEvent>
#include <QLayoutItem>
#include <QLabel>
#include <QTimer>

#include "debug.h"
#include "mainwidget.h"
#include "model/data.h"
#include "model/datacenter.h"

SessionFriendArea::SessionFriendArea()
{
    this->setStyleSheet("QWidget { background-color: rgb(229, 228, 228); }");

    // 1. 创建滚动区
    scrollArea = utils::WidgetUtil::createQScrollArea();

    // 2. 创建Widget
    container = new QWidget();
    container->setFixedWidth(310);
    scrollArea->setWidget(container);     // 指定滚动对象的参照窗口

    // 3. 为SessionFriendArea创建一个布局管理器, 用于存放滚动区
    QVBoxLayout* mainLayout = new QVBoxLayout();
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->setSpacing(0);
    mainLayout->addWidget(scrollArea);
    this->setLayout(mainLayout);

    // 4. 为存放好友项创建布局
    QVBoxLayout* contentLayout  = new QVBoxLayout();
    contentLayout ->setContentsMargins(0, 0, 0, 0);
    contentLayout ->setSpacing(0);
    contentLayout ->setAlignment(Qt::AlignTop);
    container->setLayout(contentLayout);        // 将布局设置所属widget


    // 构造测试数据
#if TEST_UI
    QIcon icon(":/resource/image/girl.jpg");
    for(int i = 0; i < 30; ++i) {
        this->addItem(SessionItemType, QString::number(i), icon, "小美" + QString::number(i), "this is last message" + QString::number(i));
    }
#endif

}

void SessionFriendArea::clear()
{
    // 先移除已选择的item
    selectItems.clear();

    QLayout* layout = container->layout();
    for(int i = layout->count() - 1; i >= 0; --i) {
        QLayoutItem* item = layout->takeAt(i);
        if(item->widget()) {
            delete item->widget();
        }
        delete item;
    }
}

void SessionFriendArea::addItem(ItemType itemType, const QString& id, const QIcon& avatar,
                                const QString& name, const QString& description)
{
    SessionFriendItem* item = nullptr;
    if (itemType == FriendItemType) {
        item = new FriendItem(this, id, avatar, name, description);
    } else if (itemType == SessionItemType) {
        item = new SessionItem(this, id, avatar, name, description);
    } else if (itemType == ApplyItemType) {
        item = new ApplyItem(this, id, avatar, name);
    } else {
        LOG(LL_ERROR, "错误的item类型: {}", itemType);
        return;
    }
    container->layout()->addWidget(item);
}

void SessionFriendArea::clickItem(int idx)
{
    if(idx < 0 || idx >= container->layout()->count()) {
        LOG(LL_WARN, "找不到位置为 {} 的元素.", idx);
        return;
    }
    QLayoutItem* layoutItem = container->layout()->itemAt(idx);
    if(!layoutItem || !layoutItem->widget()) {
        LOG(LL_WARN, "指定的元素idx:{} 的元素不存在.", idx);
        return;
    }
    SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(layoutItem->widget());
    item->select();
}

QList<SessionFriendItem*>& SessionFriendArea::getSelectItems()
{
    return selectItems;
}

void SessionFriendArea::scrollToBeginLater()
{
    QTimer* timer = new QTimer();
    connect(timer, &QTimer::timeout, this, [=](){
        int minVal = this->scrollArea->verticalScrollBar()->minimum();
        this->scrollArea->verticalScrollBar()->setValue(minVal);

        timer->stop();
        timer->deleteLater();
    });
    timer->start();
}

SessionFriendItem::SessionFriendItem(QWidget* owner, const QIcon &avatar, const QString &name, const QString &lastMessage)
    : owner(owner)
{
    this->setFixedHeight(70);
    this->setStyleSheet("QWidget { background-color: rgb(231, 230, 229); }");

    // 创建网格管理布局器
    QGridLayout* layout = new QGridLayout();
    layout->setContentsMargins(10, 0, 0, 0);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    this->setLayout(layout);

    // 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(50, 50);
    avatarBtn->setIconSize(QSize(50, 50));
    avatarBtn->setIcon(avatar);
    avatarBtn->setStyleSheet("QPushButton {background-color: rgb(231, 230, 229);}");
    avatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    // 创建名字
    QLabel* nameLabel = new QLabel();
    nameLabel->setFixedHeight(35);
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel { font-size: 18px; font-weight: 600; }");
    nameLabel->setAlignment(Qt::AlignBottom);
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 创建消息预览
    messageLabel = new QLabel();
    messageLabel->setFixedHeight(35);
    messageLabel->setText(utils::StringUtil::stringTruncated(lastMessage, owner->width() - 80));
    messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    layout->addWidget(avatarBtn, 0, 0, 2, 2);
    layout->addWidget(nameLabel, 0, 2, 1, 8);
    layout->addWidget(messageLabel, 1, 2, 1, 8);
    layout->setColumnStretch(8, 1);             // 当label宽度变小时, 设置网格指定列分配多余的宽度
}

// QWidget子类设置样式需要重写绘画ui的接口, 让QWidget回调绘画指定的样式
void SessionFriendItem::paintEvent(QPaintEvent* event)
{
    (void)event;
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void SessionFriendItem::mousePressEvent(QMouseEvent* event)
{
    (void)event;
    select();
}

void SessionFriendItem::enterEvent(QEnterEvent* event)
{
    (void)event;
    if(!selected) {
        this->setStyleSheet("QWidget {background-color: rgb(216, 215, 215);}");
    }
}

void SessionFriendItem::leaveEvent(QEvent* event)
{
    (void)event;
    if(!selected) {
        this->setStyleSheet("QWidget {background-color: rgb(229, 228, 228);}");
    }
}

void SessionFriendItem::select()
{
    // 撤销上此选中元素的样式
    // parentWidget访问SessionFriendArea::contain
    SessionFriendArea* own_ptr = dynamic_cast<SessionFriendArea*>(owner);
    QList<SessionFriendItem*>& selectItems = own_ptr->getSelectItems();
    for(auto& item : selectItems) {
        item->selected = false;
        item->setStyleSheet("background-color: rgb(231, 230, 229);");
    }
    selectItems.clear();

    this->setStyleSheet("QWidget { background-color: rgb(210, 209, 209); }");
    this->selected = true;
    selectItems.emplace_back(this);

    active();
}

void SessionFriendItem::active()
{
    if (func)
        (this->*func)();
}



SessionItem::SessionItem(QWidget* owner, const QString& chatSessionId, const QIcon& avatar,
                         const QString& name, const QString& lastMsg)
    : SessionFriendItem(owner, avatar, name, lastMsg)
    , chatSessionId(chatSessionId)
    , lastMessage(lastMsg)
{
    func = reinterpret_cast<FuncPtr>(&SessionItem::activeImpl);

    // 更新该会话的最近消息
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::updateLastMessage, this, &SessionItem::updateLastMessage);

    // 新的会话创建, 要恢复历史未读消息记录
    int unread = dataCenter->getUnread(chatSessionId);
    if(unread) {
        QString msgPreview = QString("[未读%1条] ").arg(unread) + lastMessage;
        this->messageLabel->setText(utils::StringUtil::stringTruncated(msgPreview, owner->width() - 90));
    }
}

QString SessionItem::getChatSessionId()
{
    return chatSessionId;
}

void SessionItem::activeImpl()
{
    LOG(LL_DEBUG, "SessionItem active, chatSessionId: {}", getChatSessionId());

    // 选中该会话时, 加载最近消息
    MainWidget* mainWidget = MainWidget::getInstance();
    mainWidget->loadRecentMessages(getChatSessionId());

    // 更新会话列表的消息预览状态
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->claerUnread(chatSessionId);
    this->messageLabel->setText(utils::StringUtil::stringTruncated(lastMessage, owner->width() - 80));
}

void SessionItem::updateLastMessage(const QString &chatSessionId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    // 只有匹配的会话才需要更新
    if(chatSessionId != this->chatSessionId) return;

    // 获取最后一条消息
    QList<model::Message>* messageList = dataCenter->getRecentMessageList(chatSessionId);
    if(!messageList || messageList->empty()) {
        return;
    }

    const model::Message& msg = messageList->back();

    // 消息分类
    QString text;
    if (msg.messageType == model::TEXT_TYPE) {
        text = msg.content;
    } else if (msg.messageType == model::IMAGE_TYPE) {
        text = "[图片]";
    } else if (msg.messageType == model::FILE_TYPE) {
        text = "[文件]";
    } else if (msg.messageType == model::SPEECH_TYPE) {
        text = "[语音]";
    } else {
        text = "[未知类型消息]";
    }

    // 更新界面
    // 当前会话即新消息所属会话, 正常显示预览消息, 否则维护未读状态
    if(chatSessionId == dataCenter->getCurrentChatSessionId()) {
        this->messageLabel->setText(utils::StringUtil::stringTruncated(lastMessage, owner->width() - 80));
    } else {
        int unread = dataCenter->getUnread(chatSessionId);
        if(unread) {
            QString msgPreview = QString("[未读%1条] ").arg(unread) + lastMessage;
            this->messageLabel->setText(utils::StringUtil::stringTruncated(msgPreview, owner->width() - 90));
        }
    }
}



FriendItem::FriendItem(QWidget* owner, const QString& userId, const QIcon& avatar,
                       const QString& name, const QString& description)
    : SessionFriendItem(owner, avatar, name, description)
    , userId(userId)
{
    func = reinterpret_cast<FuncPtr>(&FriendItem::activeImpl);
}

QString FriendItem::getUserId()
{
    return userId;
}

void FriendItem::activeImpl()
{
    LOG(LL_DEBUG, "FriendItem active, userId: {}", getUserId());

    MainWidget* mainWidget = MainWidget::getInstance();
    mainWidget->switchToSession(getUserId());
}

ApplyItem::ApplyItem(QWidget* owner, const QString& userId, const QIcon& avatar, const QString& name)
    : SessionFriendItem(owner, avatar, name, "")
    , userId(userId)
{
    func = reinterpret_cast<FuncPtr>(&ApplyItem::activeImpl);

    // 移除信息框
    QGridLayout* layout = dynamic_cast<QGridLayout*>(this->layout());
    layout->removeWidget(messageLabel);
    delete messageLabel;

    // 创建申请交互按钮
    QPushButton* acceptBtn = new QPushButton();
    acceptBtn->setText("接受");
    QPushButton* rejectBtn = new QPushButton();
    rejectBtn->setText("拒绝");

    layout->addWidget(acceptBtn, 1, 2, 1, 1);
    layout->addWidget(rejectBtn, 1, 3, 1, 1);

    connect(acceptBtn, &QPushButton::clicked, this, &ApplyItem::onClickedByAcceptBtn);
    connect(rejectBtn, &QPushButton::clicked, this, &ApplyItem::onClickedByRejectBtn);
}

void ApplyItem::activeImpl()
{
    LOG(LL_DEBUG, "ApplyItem active");
}

void ApplyItem::onClickedByAcceptBtn()
{
    // 同意好友响应是关于主窗口界面的处理, 因此关联响应处理的信号槽放在 MainWidget 处理
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->friendApplyProcessAysnc(userId, true);
}

void ApplyItem::onClickedByRejectBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->friendApplyProcessAysnc(userId, false);
}


